package cz.possoft.serializable.four.jaxb;

import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;

import cz.possoft.converter.jaxb.JAXBGameConverter;
import cz.possoft.generic.utils.GenericUtils;
import cz.possoft.serializable.four.figurky.FourFigurka;
import cz.possoft.serializable.four.game.FourGame;
import cz.possoft.serializable.four.game.FourPole;
import cz.possoft.serializable.four.jaxb.classes.FourFigurkaType;
import cz.possoft.serializable.four.jaxb.classes.FourGameType;
import cz.possoft.serializable.four.jaxb.classes.FourPoleType;
import cz.possoft.serializable.four.jaxb.classes.ObjectFactory;

/**
 * 
 * @author mposolda
 */
public class FourJAXBGameConverter implements JAXBGameConverter<FourGame> {
	
	private static FourJAXBGameConverter instance = new FourJAXBGameConverter();
	
	private FourJAXBGameConverter() {}
	
	public static FourJAXBGameConverter getInstance() {
		return instance;
	}	

	public JAXBElement<?> convertGameToJAXBElement(FourGame game) {
		ObjectFactory oFactory = new ObjectFactory();
		FourGameType fourType = oFactory.createFourGameType();
		
		// Generic
		fourType.setWhitePlayerName(game.getWhitePlayerName());
		fourType.setBlackPlayerName(game.getBlackPlayerName());
		fourType.setWhiteNaTahu(game.isWhiteNaTahu());
		fourType.setMeWhite(game.isMeWhite());
		fourType.setGameBegin(game.isGameBegin());
		fourType.setActive(game.isActive());
		fourType.setEndState(game.isEndState());	
		
		// specific to four
		fourType.setFourPole(convertFourPoleToXML((FourPole)game.getHraciPole(), oFactory));
		return oFactory.createFourGame(fourType);
	}

	public FourGame convertJAXBElementToGame(JAXBElement<?> element) {
		FourGameType fourType = (FourGameType)element.getValue(); 
		FourGame game = new FourGame();
		
		// Generic
		game.setWhitePlayerName(fourType.getWhitePlayerName());
		game.setBlackPlayerName(fourType.getBlackPlayerName());
		game.setWhiteNaTahu(fourType.isWhiteNaTahu());
		game.setMeWhite(fourType.isMeWhite());
		game.setGameBegin(fourType.isGameBegin());
		game.setActive(fourType.isActive());
		game.setEndState(fourType.isEndState());	
		
		// Specific to chess
		game.setHraciPole(convertXMLToSachovnice(fourType.getFourPole()));		
		
		return game;		
	}

	public JAXBContext getJAXBContext() {
		try {
			return JAXBContext.newInstance("cz.possoft.serializable.four.jaxb.classes", FourJAXBGameConverter.class.getClassLoader());
		}
		catch (JAXBException je) {
			je.printStackTrace();
			throw new RuntimeException("Can't create JAXB context.", je);
		}		
	}
	
	/* PRIVATE METHODS */
	
	// 1) Methods for converting java types to XML types. 
	
	private FourPoleType convertFourPoleToXML(FourPole fourPole, ObjectFactory oFactory) {
		FourPoleType result = oFactory.createFourPoleType();
		
		// naplneni figurek
		List<FourFigurkaType> figurky = result.getFourFigurka();
		for (int i=0 ; i<7 ; i++)
			for (int j=0 ; j<7 ; j++) {
				FourFigurka fig = fourPole.getFigurka(i, j);
				// prazdny pole nezapisujeme do XML.
				if (fig.getColor() == GenericUtils.COLOR_NEUTRAL) {
					continue;
				}
				FourFigurkaType figType = oFactory.createFourFigurkaType();
				figType.setX(fig.getX());
				figType.setY(fig.getY());
				figType.setColor(fig.getColor());
				figType.setIsPartOfWinningLine(fig.isPartOfWinningLine());
				figurky.add(figType);
			}
		return result;		
	}
	
	// 2) Methods for converting XML types to java types. 

	private FourPole convertXMLToSachovnice(FourPoleType fourPoleType) {
		FourPole result = new FourPole(false);
		
		// naplneni figurek
		List<FourFigurkaType> figurky = fourPoleType.getFourFigurka();
		for (FourFigurkaType figType : figurky) {
				FourFigurka figurka = new FourFigurka(figType.getX(), figType.getY(), result);
				figurka.setColor(figType.getColor());
				figurka.setPartOfWinningLine(figType.isIsPartOfWinningLine());
				result.setFigurka(figurka.getX(), figurka.getY(), figurka);
		}
		return result;
	}
}
